# -*- coding: utf-8 -*-
#
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.

"""赋值语句发射器"""

from typing import Optional

from mcpy.ir.base import IRNode
from mcpy.ir.statements.assignment import IRAssign, IRAugAssign
from mcpy.ir.expressions import IRName, IRAttribute
from mcpy.ir.expressions.access import IRSubscript
from ..core.emitter import EmitResult, NodeTypeEmitter
from ..core.context import CodeGenContext
from ..core.generator import get_global_generator
from ...template_system import replace_template_params
from mcpy.ir.base import get_default_ir_node
from mcpy.type_system import get_cpp_type
from mcpy.ir.expressions.lambda_expr import IRLambda
from mcpy.ir.declarations.function import IRFunctionNode
from mcpy.symbol_meta import TypeKind


class AssignmentEmitter(NodeTypeEmitter):
    """处理赋值语句的发射器

    迁移自IRAssign.render和IRAugAssign.render方法，支持：
    - 普通赋值：target = value
    - 类型注解赋值：type target = value
    - 增强赋值：target += value
    """

    def __init__(self):
        super().__init__([IRAssign, IRAugAssign])

    def emit(self, node: IRNode, context: CodeGenContext) -> EmitResult:
        """生成赋值语句代码"""
        if isinstance(node, IRAssign):
            return self._emit_assign(node, context)
        elif isinstance(node, IRAugAssign):
            return self._emit_aug_assign(node, context)
        else:
            raise ValueError(f"Unsupported assignment node type: {type(node)}")

    def _emit_assign(self, node: IRAssign, context: CodeGenContext) -> EmitResult:
        """生成普通赋值语句代码"""

        generator = get_global_generator()

        # 检查是否是多目标赋值或元组解包赋值
        target_exprs = node.get_target_exprs()
        if len(target_exprs) > 1:
            # 区分多目标赋值和元组解包赋值
            if self._is_tuple_unpacking(node):
                return self._emit_tuple_unpacking_assign(node, context)
            else:
                return self._emit_multi_target_assign(node, context)

        # 单目标赋值处理
        # 获取单目标表达式
        target_expr = node.get_target_expr()
        if not target_expr:
            # 没有目标表达式，可能是特殊赋值（如 __setitem__ 调用）
            # 生成值表达式作为语句
            value_context = context.create_child_context(in_assignment=True)
            value_code = generator.generate_expression(node.value, value_context)
            return EmitResult(code=f"{value_code};", precedence=0)

        # 检查是否是下标赋值（切片或索引）
        from mcpy.ir.expressions import IRSubscript

        if isinstance(target_expr, IRSubscript):
            # 先尝试切片赋值
            slice_assign_code = self._try_emit_slice_assign(
                target_expr, node.value, context
            )
            if slice_assign_code:
                return EmitResult(code=slice_assign_code, precedence=0)

            # 再尝试索引赋值（使用 __setitem__）
            value_context = context.create_child_context(in_assignment=True)
            value_code = generator.generate_expression(node.value, value_context)

            obj_code = generator.generate_expression(target_expr.value, context)

            setitem_code = self._try_emit_setitem_method(
                target_expr, obj_code, value_code, context
            )
            if setitem_code:
                return EmitResult(code=setitem_code, precedence=0)

        # 检查是否有C++类型信息
        cpp_type = node.get_extension_param("cpp_type")

        # 检查是否是栈模式的 lambda（优先处理）
        if isinstance(node.value, IRLambda):
            storage_mode = node.value.get_extension_param("storage_mode")
            if storage_mode == "stack":
                # 栈 lambda：使用 lambda 的 cpp_type（functor 名称）
                lambda_cpp_type = node.value.get_extension_param("cpp_type")
                if lambda_cpp_type and lambda_cpp_type.startswith("__lambda_"):
                    cpp_type = lambda_cpp_type

        # 如果没有，从目标表达式或符号表中获取
        if not cpp_type:
            cpp_type = context.get_cpp_type(target_expr)

        # 如果还没有，尝试从符号表查找
        if not cpp_type and isinstance(target_expr, IRName):
            if context.current_node:
                target_symbol = context.current_node.lookup_symbol(target_expr.id)
                if target_symbol:
                    cpp_type = get_cpp_type(target_symbol.type_info, target_expr)

        # 获取目标名称
        target_name = self._get_target_name(target_expr)

        # 最后的回退：从右侧表达式的 inferred_type 推导
        if not cpp_type:
            value_inferred_type = node.value.get_extension_param("inferred_type")
            if value_inferred_type:
                cpp_type = get_cpp_type(value_inferred_type, target_expr)

        # 处理多目标赋值的情况
        if node.has_extension_param("target_declarations"):
            # 多目标赋值，需要检查当前目标是否是声明
            target_declarations = node.get_extension_param("target_declarations", {})
            is_declaration = target_declarations.get(target_name, False)
        else:
            # 单目标赋值
            is_declaration = node.get_extension_param("is_variable_declaration", False)

        # 检查是否是默认节点（无初始值的类型注解）
        is_default_node = (
            node.value.node_type == "default" or node.value is get_default_ir_node()
        )

        # 如果是默认节点且是声明，根据类型生成默认值
        if is_default_node and is_declaration:
            # 例如：
            # v1: str
            # v2: bool
            value_code = self._get_default_value_for_type(cpp_type, target_expr)
        else:
            value_context = context.create_child_context(
                in_assignment=True,
                expected_cpp_type=cpp_type,  # 传递期望类型，让表达式生成器可以使用初始化列表
            )
            value_code = generator.generate_expression(node.value, value_context)

            # 检查是否需要自动类型转换（variant 到强类型）
            value_code = self._apply_type_conversion(
                value_code, node.value, cpp_type, context
            )

        # 检查是否是栈模式的 lambda 或嵌套函数（特殊处理）
        closure_node = None  # 可以是 IRLambda 或 IRFunctionNode
        if isinstance(node.value, IRLambda):
            storage_mode = node.value.get_extension_param("storage_mode")
            if storage_mode == "stack":
                closure_node = node.value
        elif isinstance(node.value, IRFunctionNode):
            # 嵌套函数（复用 lambda 机制）
            storage_mode = node.value.get_extension_param("storage_mode")
            if storage_mode == "stack":
                closure_node = node.value

        if closure_node and is_declaration:
            # 栈闭包（lambda 或嵌套函数）：只声明，不初始化
            # 获取捕获变量列表
            # Lambda 和嵌套函数都使用 captured_vars 属性
            captured_vars = closure_node.captured_vars or []

            if captured_vars:
                # 有捕获变量：需要传递捕获的变量
                # 生成：__lambda_X target_name(captured_vars...);
                # 或：__nested_func_X target_name(captured_vars...);
                captures = ", ".join(captured_vars)
                code = f"{cpp_type} {target_name}({captures});"
            else:
                # 无捕获变量：默认构造
                # 生成：__lambda_X target_name;
                # 或：__nested_func_X target_name;
                code = f"{cpp_type} {target_name};"
        elif cpp_type and is_declaration:
            # 首次声明：检查是否需要 shared_ptr 包装
            # 标记由 TypeReplacementPass 预先设置
            needs_shared_ptr = node.get_extension_param("needs_shared_ptr", False)

            if needs_shared_ptr:
                # 需要 shared_ptr 包装（闭包变量被多 lambda 共享或修改）
                code = (
                    f"auto {target_name} = std::make_shared<{cpp_type}>({value_code});"
                )
            elif self._should_use_auto_deduction(cpp_type, node, target_name):
                # 需要auto推导（模板参数或不完整泛型）
                code = f"auto {target_name} = {value_code};"
            else:
                # 普通声明
                code = f"{cpp_type} {target_name} = {value_code};"
        elif node.annotation and is_declaration:
            # 有注解的首次声明：检查是否需要 shared_ptr 包装
            # 标记由 TypeReplacementPass 预先设置
            needs_shared_ptr = node.get_extension_param("needs_shared_ptr", False)

            if needs_shared_ptr:
                # 需要 shared_ptr 包装
                # 注意：使用 cpp_type 而不是 annotation（annotation 是 Python 类型）
                if cpp_type:
                    code = f"auto {target_name} = std::make_shared<{cpp_type}>({value_code});"
                else:
                    # 回退：使用 mc::variant（因为 annotation 可能是 Callable 等复杂类型）
                    code = f"auto {target_name} = std::make_shared<mc::variant>({value_code});"
            else:
                # 普通声明：使用 cpp_type 而不是 Python annotation
                if cpp_type:
                    code = f"{cpp_type} {target_name} = {value_code};"
                else:
                    # 回退：使用 mc::variant（Callable 等复杂类型都映射为 variant）
                    code = f"mc::variant {target_name} = {value_code};"
        else:
            # 重新赋值或无类型信息的赋值
            target_code = self._generate_target_code_from_expr(target_expr)
            code = f"{target_code} = {value_code};"

        return EmitResult(code=code, precedence=0)

    def _emit_multi_target_assign(
        self, node: IRAssign, context: CodeGenContext
    ) -> EmitResult:
        """生成多目标赋值代码

        将 a = b = c = 10 转换为：
        int c = 10;
        int b = c;
        int a = b;
        """
        from ..core.generator import get_global_generator

        generator = get_global_generator()

        # 生成值表达式
        value_code = generator.generate_expression(node.value, context)

        # 获取目标声明信息
        target_declarations = node.get_extension_param("target_declarations", {})

        # 从右到左生成赋值语句
        statements = []
        target_exprs = node.get_target_exprs()
        target_names = [self._get_target_name(expr) for expr in target_exprs]

        # 最后一个目标直接赋值原始值
        last_target = target_names[-1]
        last_is_declaration = target_declarations.get(last_target, False)

        if last_is_declaration:
            # 获取类型信息
            cpp_type = context.get_cpp_type(node)
            if not cpp_type:
                cpp_type = "auto"
            statements.append(f"{cpp_type} {last_target} = {value_code};")
        else:
            statements.append(f"{last_target} = {value_code};")

        # 其他目标从右到左依次赋值
        for i in range(len(target_names) - 2, -1, -1):
            current_target = target_names[i]
            previous_target = target_names[i + 1]
            is_declaration = target_declarations.get(current_target, False)

            if is_declaration:
                # 获取类型信息
                cpp_type = context.get_cpp_type(node)
                if not cpp_type:
                    cpp_type = "auto"
                statements.append(f"{cpp_type} {current_target} = {previous_target};")
            else:
                statements.append(f"{current_target} = {previous_target};")

        # 合并所有语句
        code = "\n".join(statements)
        return EmitResult(code=code, precedence=0)

    def _is_tuple_unpacking(self, node: IRAssign) -> bool:
        """判断是否是元组解包赋值

        元组解包：x, y = (5, 10) 或 x, y = some_tuple
        多目标赋值：x = y = 10

        区分方法：使用 IR 节点的标记
        """
        return node.is_tuple_unpacking

    def _emit_tuple_unpacking_assign(
        self, node: IRAssign, context: CodeGenContext
    ) -> EmitResult:
        """生成元组解包赋值代码

        策略1：直接字面量解包 (x, y = 1, 2)
        int x = 1;
        int y = 2;

        策略2：可迭代对象解包 (x, y = some_iterable)
        auto unpacked = mcpy::unpack<2>(some_iterable);
        int x = mcpy::get_unpacked<0>(unpacked);
        int y = mcpy::get_unpacked<1>(unpacked);
        """
        from ..core.generator import get_global_generator

        generator = get_global_generator()

        # 获取目标声明信息
        target_declarations = node.get_extension_param("target_declarations", {})
        target_exprs = node.get_target_exprs()
        target_names = [self._get_target_name(expr) for expr in target_exprs]
        statements = []

        # 策略选择：根据右操作数类型决定解包方式
        if self._is_direct_literal_unpacking(node):
            # 策略1：直接字面量解包
            return self._emit_direct_literal_unpacking(
                node, context, target_names, target_declarations
            )
        else:
            # 策略2：可迭代对象解包
            return self._emit_iterable_unpacking(
                node, context, target_names, target_declarations
            )

    def _is_direct_literal_unpacking(self, node: IRAssign) -> bool:
        """判断是否是直接字面量解包

        直接字面量：x, y = 1, 2 或 x, y = (1, 2) 或 x, y = [1, 2]
        """
        from ...ir.expressions.literals import IRTuple, IRList

        value = node.value
        return isinstance(value, (IRTuple, IRList)) and hasattr(value, "elements")

    def _emit_direct_literal_unpacking(
        self,
        node: IRAssign,
        context: CodeGenContext,
        target_names: list,
        target_declarations: dict,
    ) -> EmitResult:
        """生成直接字面量解包代码"""
        from ..core.generator import get_global_generator

        generator = get_global_generator()
        statements = []

        # 直接为每个目标生成赋值语句
        for i, target_name in enumerate(target_names):
            is_declaration = target_declarations.get(target_name, False)

            # 获取对应的元素表达式
            element = getattr(node.value, "elements", [])[i]
            element_code = generator.generate_expression(element, context)

            if is_declaration:
                # 从类型推断阶段获取已推断的类型
                cpp_type = self._get_target_cpp_type(node, target_name, context)
                # 不完整的类型需要使用auto让编译器推导
                if self._should_use_auto_deduction(cpp_type, node, target_name):
                    cpp_type = "auto"
                statements.append(f"{cpp_type} {target_name} = {element_code};")
            else:
                statements.append(f"{target_name} = {element_code};")

        code = "\n".join(statements)
        return EmitResult(code=code, precedence=0)

    def _emit_iterable_unpacking(
        self,
        node: IRAssign,
        context: CodeGenContext,
        target_names: list,
        target_declarations: dict,
    ) -> EmitResult:
        """生成可迭代对象解包代码

        策略：
        1. 如果右值是简单表达式（变量名），直接解包
        2. 如果右值是复杂表达式（函数调用等），先存储到临时变量，避免重复求值
        """
        from ..core.generator import get_global_generator
        from ...ir.expressions import IRName

        generator = get_global_generator()
        statements = []

        # 生成右操作数表达式
        value_code = generator.generate_expression(node.value, context)

        # 判断是否需要临时变量：如果右值不是简单的变量名，则需要临时变量
        need_temp_var = not isinstance(node.value, IRName)

        if need_temp_var:
            # 使用临时变量存储右值，避免重复求值
            # 使用第一个目标变量名生成有意义且稳定的临时变量名
            first_target = target_names[0] if target_names else "tuple"
            temp_var_name = f"__{first_target}_tuple"
            statements.append(f"auto {temp_var_name} = {value_code};")
            source_expr = temp_var_name
        else:
            # 右值是简单变量，直接使用
            source_expr = value_code

        # 为每个目标生成解包语句
        for i, target_name in enumerate(target_names):
            is_declaration = target_declarations.get(target_name, False)

            if is_declaration:
                # 从类型推断阶段获取已推断的类型
                cpp_type = self._get_target_cpp_type(node, target_name, context)
                statements.append(
                    f"{cpp_type} {target_name} = mcpy::unpack_get<{i}>({source_expr});"
                )
            else:
                statements.append(
                    f"{target_name} = mcpy::unpack_get<{i}>({source_expr});"
                )

        # 合并所有语句
        code = "\n".join(statements)
        return EmitResult(code=code, precedence=0)

    def _get_target_cpp_type(
        self, node: IRAssign, target_name: str, context: CodeGenContext
    ) -> str:
        """获取目标变量的 C++ 类型

        Args:
            node: 赋值节点
            target_name: 目标变量名
            context: 代码生成上下文

        Returns:
            str: C++ 类型字符串
        """
        return context.get_assignment_target_cpp_type(node, target_name)

    def _should_use_auto_deduction(
        self, cpp_type: str, node: IRAssign, target_name: str
    ) -> bool:
        """判断是否应该使用auto类型推导

        通过符号表查询类型信息，在以下情况使用auto：
        1. 类型是TEMPLATE或TYPE_PARAM（TypeVar） - C++模板参数不能直接声明变量
        2. 类型是Protocol类型（如Iterator[T]） - Protocol类型映射为mc::variant，但实际C++类型是具体类型

        Args:
            cpp_type: C++类型字符串
            node: 赋值节点
            target_name: 目标变量名

        Returns:
            bool: 是否应该使用auto
        """
        if not cpp_type or cpp_type == "auto":
            return False

        # 从符号表查询类型信息
        symbol = node.lookup_symbol(target_name)
        if not symbol or not symbol.type_info:
            # 符号未找到或无类型信息，使用原类型（让C++编译器报错）
            return False

        # 如果类型是TEMPLATE或TYPE_PARAM（TypeVar），需要auto
        if symbol.type_info.kind in (TypeKind.TEMPLATE, TypeKind.TYPE_PARAM):
            return True

        # 如果类型是Protocol类型（如Iterator[T]），需要auto
        # Protocol类型在get_cpp_type中被映射为mc::variant，但实际C++类型是具体类型
        # 使用auto让C++编译器自动推导具体类型
        # 注意：需要使用 is_protocol_type() 函数，因为 Protocol 类型的 kind 可能是 GENERIC
        from mcpy.type_system import is_protocol_type

        if is_protocol_type(symbol.type_info, node):
            return True

        return False

    def _emit_aug_assign(
        self, node: IRAugAssign, context: CodeGenContext
    ) -> EmitResult:
        """生成增强赋值语句代码

        迁移自IRAugAssign.render方法
        支持操作符重载
        """
        from ..core.generator import get_global_generator

        generator = get_global_generator()

        # 生成值表达式
        value_code = generator.generate_expression(node.value, context)

        # 获取目标表达式并生成代码
        # IRAugAssign 目前只支持字符串目标
        if isinstance(node, IRAugAssign):
            target_code = self._generate_target_code(node.target)
        else:
            target_expr = node.get_target_expr()
            if target_expr:
                target_code = self._generate_target_code_from_expr(target_expr)
            else:
                # 回退到旧机制
                target_code = self._generate_target_code(node.target)

        # 尝试使用增强赋值方法重载（__iadd__, __ior__ 等）
        overload_code = self._try_aug_assign_method_overload(
            node, target_code, value_code, context
        )
        if overload_code:
            return EmitResult(code=overload_code, precedence=0)

        # 检查是否需要类型转换（Any -> 强类型）
        # 如果右操作数是 Any 类型，需要进行类型转换
        value_code = self._apply_aug_assign_type_conversion(
            value_code, node, target_code, context
        )

        # 处理特殊的增强赋值操作符
        if node.op == "**":
            # 幂运算：target **= value -> target = mc::pow(target, value)
            code = f"{target_code} = mc::pow({target_code}, {value_code});"
        elif node.op == "//":
            # 整数除法：target //= value -> target /= value
            code = f"{target_code} /= {value_code};"
        else:
            # 普通增强赋值操作符
            code = f"{target_code} {node.op}= {value_code};"

        return EmitResult(code=code, precedence=0)

    def _try_aug_assign_method_overload(
        self,
        node: IRAugAssign,
        target_code: str,
        value_code: str,
        context: CodeGenContext,
    ) -> str | None:
        """尝试使用增强赋值方法重载

        查找并调用对应的魔法方法（__iadd__, __ior__ 等）

        Args:
            node: 增强赋值节点
            target_code: 目标变量的生成代码
            value_code: 右操作数的生成代码
            context: 代码生成上下文

        Returns:
            str | None: 如果找到方法重载则返回生成的代码，否则返回 None
        """
        # 操作符到魔法方法的映射
        op_to_method = {
            "+": "__iadd__",
            "-": "__isub__",
            "*": "__imul__",
            "/": "__itruediv__",
            "//": "__ifloordiv__",
            "%": "__imod__",
            "**": "__ipow__",
            "<<": "__ilshift__",
            ">>": "__irshift__",
            "&": "__iand__",
            "^": "__ixor__",
            "|": "__ior__",
        }

        method_name = op_to_method.get(node.op)
        if not method_name or not context.current_node:
            return None

        # 获取目标变量的类型
        target_symbol = context.current_node.lookup_symbol(node.target)
        if not target_symbol or not target_symbol.type_info:
            return None

        target_type = target_symbol.type_info

        # 获取右操作数的类型
        value_type = (
            node.value.get_extension_param("inferred_type") if node.value else None
        )
        args_types = [value_type] if value_type else []

        # 查找增强赋值方法
        method_symbol = context.current_node.lookup_symbol(
            method_name,
            owner_type=target_type,
            func_args=args_types,
        )

        if not method_symbol:
            return None

        # 获取匹配的签名
        full_args_types = [target_type] + args_types
        matching_signature = method_symbol.find_matching_signature(full_args_types)
        if not matching_signature:
            if method_symbol.signatures:
                matching_signature = method_symbol.signatures[0]
            else:
                return None

        # 获取模板
        template = matching_signature.emit_template
        if not template:
            return None

        # 添加必要的包含文件
        for include in matching_signature.includes:
            context.require_include(include)

        # 替换模板参数
        code = replace_template_params(
            template, matching_signature, [target_code, value_code]
        )

        return f"{code};"

    def _apply_aug_assign_type_conversion(
        self,
        value_code: str,
        node: IRAugAssign,
        target_code: str,
        context: CodeGenContext,
    ) -> str:
        """为增强赋值运算符应用类型转换

        如果右操作数是 Any 类型，需要使用 mcpy::cast 进行类型转换，
        因为 C++ 不支持 int += mc::variant 这样的增强赋值运算符。

        Args:
            value_code: 右操作数的生成代码
            node: 增强赋值节点
            target_code: 目标变量的生成代码
            context: 代码生成上下文

        Returns:
            str: 可能经过类型转换的代码
        """
        from mcpy.codegen.utils.type_conversion import generate_variant_cast
        from ...type_system import get_cpp_type

        # 检查右操作数是否是 Any 类型
        if not hasattr(node, "value") or not node.value:
            return value_code

        # 获取右操作数的 C++ 类型
        value_cpp_type = context.get_cpp_type(node.value)

        # 检查是否是 mc::variant（Any 类型）
        if not value_cpp_type or value_cpp_type != "mc::variant":
            return value_code

        # 右操作数是 Any，需要获取目标变量的类型进行转换
        # 通过符号表查找目标变量的类型
        if not context.current_node:
            return value_code

        target_symbol = context.current_node.lookup_symbol(node.target)
        if (
            not target_symbol
            or not target_symbol.type_info
            or target_symbol.type_info.kind == TypeKind.ANY
        ):
            # 目标变量类型未知或为 Any 类型，不需要转换
            return value_code

        target_cpp_type = get_cpp_type(target_symbol.type_info, context.current_node)
        if not target_cpp_type or target_cpp_type == "mc::variant":
            return value_code

        # 应用类型转换
        context.require_include("mcpy/builtins.h")
        return generate_variant_cast(value_code, target_cpp_type)

    def _get_target_name(self, target_expr) -> str:
        """从目标表达式获取变量名

        Args:
            target_expr: 目标表达式 (IRExpr)

        Returns:
            str: 变量名
        """
        if isinstance(target_expr, IRName):
            return target_expr.id
        elif isinstance(target_expr, IRAttribute):
            # 对于属性访问，返回完整的属性路径
            if isinstance(target_expr.value, IRName):
                return f"{target_expr.value.id}.{target_expr.attr}"
            else:
                # 复杂的属性访问，暂时返回属性名
                return target_expr.attr
        else:
            # 其他类型的表达式，返回字符串表示
            return str(target_expr)

    def _generate_target_code_from_expr(self, target_expr) -> str:
        """从目标表达式生成目标代码

        Args:
            target_expr: 目标表达式 (IRExpr)

        Returns:
            str: 生成的目标代码
        """
        from mcpy.ir.expressions import IRName, IRAttribute, IRSubscript

        if isinstance(target_expr, IRName):
            return target_expr.id
        elif isinstance(target_expr, IRAttribute):
            # 处理属性访问
            if isinstance(target_expr.value, IRName) and target_expr.value.id == "self":
                # self.attr -> this->attr
                return f"this->{target_expr.attr}"
            else:
                # 其他属性访问
                from ..core.generator import get_global_generator

                generator = get_global_generator()
                # 这里需要上下文，暂时简化处理
                return f"{target_expr.value}.{target_expr.attr}"
        elif isinstance(target_expr, IRSubscript):
            # 处理下标访问赋值
            # 策略：利用类型配置中的 __getitem__ 方法配置获取引用
            from ..core.generator import get_global_generator
            from ..core.context import CodeGenContext

            generator = get_global_generator()
            context = CodeGenContext()

            obj_code = generator.generate_expression(target_expr.value, context)
            index_code = generator.generate_expression(target_expr.slice, context)

            # 尝试使用类型配置的 __getitem__ 方法（获取引用用于赋值）
            getitem_code = self._try_get_subscript_reference(
                target_expr, obj_code, index_code, context
            )
            if getitem_code:
                return getitem_code

            # 没有找到配置，使用标准的 [] 操作符
            return f"{obj_code}[{index_code}]"
        else:
            # 其他类型的表达式，返回字符串表示
            return str(target_expr)

    def _try_emit_slice_assign(
        self, target_expr: "IRSubscript", value_node: "IRNode", context: CodeGenContext
    ) -> str | None:
        """尝试生成切片赋值代码

        Args:
            target_expr: 目标下标表达式
            value_node: 值节点
            context: 代码生成上下文

        Returns:
            str | None: 生成的切片赋值代码，如果不是切片则返回 None
        """
        from ..core.generator import get_global_generator
        from ...ir.expressions.access import IRSlice

        # 检查是否是切片
        if not isinstance(target_expr.slice, IRSlice):
            return None

        slice_info = target_expr.slice

        generator = get_global_generator()

        # 生成对象代码
        obj_code = generator.generate_expression(target_expr.value, context)

        # 生成值代码
        value_code = generator.generate_expression(value_node, context)

        # 提取 start, stop, step
        start_code = "INT64_MIN"
        stop_code = "INT64_MIN"
        step_code = "1"

        if slice_info.lower is not None:
            start_code = generator.generate_expression(slice_info.lower, context)

        if slice_info.upper is not None:
            stop_code = generator.generate_expression(slice_info.upper, context)

        if slice_info.step is not None:
            step_code = generator.generate_expression(slice_info.step, context)

        # 添加必要的包含文件
        context.require_include("mcpy/builtins.h")
        context.require_include("<cstdint>")

        # 生成切片赋值调用代码
        code = f"mcpy::list_slice_assign({obj_code}, {value_code}, {start_code}, {stop_code}, {step_code});"

        return code

    def _try_emit_setitem_method(
        self,
        node: IRSubscript,
        obj_code: str,
        value_code: str,
        context: CodeGenContext,
    ) -> str | None:
        """尝试使用 __setitem__ 方法生成索引赋值代码

        Args:
            node: 下标访问节点
            obj_code: 对象表达式代码
            value_code: 值表达式代码
            context: 代码生成上下文

        Returns:
            str | None: 生成的代码，如果不支持则返回 None
        """
        from ..core.generator import get_global_generator

        generator = get_global_generator()
        # 获取对象的类型信息
        type_info = node.value.get_extension_param("inferred_type")
        if not type_info:
            return None

        # 获取索引和值的类型信息
        index_type = node.slice.get_extension_param("inferred_type")
        value_type = node.get_extension_param("inferred_type")  # 这是赋值节点的类型
        args_types = (
            [index_type, value_type]
            if index_type and value_type
            else [index_type] if index_type else []
        )

        # 查找 __setitem__ 方法符号
        method_symbol = None
        if context.current_node:
            method_symbol = context.current_node.lookup_symbol(
                "__setitem__",
                owner_type=type_info,
                func_args=args_types,
            )

        if not method_symbol:
            return None

        # 获取匹配的签名（需要包含 self）

        full_args_types = [type_info] + args_types
        matching_signature = method_symbol.find_matching_signature(full_args_types)
        if not matching_signature:
            if method_symbol.signatures:
                matching_signature = method_symbol.signatures[0]
            else:
                return None

        template = matching_signature.emit_template
        if not template:
            return None

        # 添加必要的包含文件
        includes = getattr(matching_signature, "includes", [])
        for include in includes:
            context.require_include(include)

        # 获取索引参数的期望类型
        expected_index_cpp_type = self._get_index_expected_type(
            method_symbol, matching_signature, node, context
        )

        # 生成索引表达式（传递期望类型）
        index_context = context.create_child_context(
            expected_cpp_type=expected_index_cpp_type
        )
        index_code = generator.generate_expression(
            node.slice, index_context, parent_precedence=100
        )

        # 应用类型转换（如果需要：mc::variant -> int）
        if expected_index_cpp_type:
            actual_index_cpp_type = context.get_cpp_type(node.slice)
            index_code = self._apply_index_type_conversion(
                index_code, actual_index_cpp_type, expected_index_cpp_type, context
            )

        # 替换模板中的占位符
        code = (
            template.replace("{self}", obj_code)
            .replace("{index}", index_code)
            .replace("{value}", value_code)
        )
        return f"{code};"

    def _get_index_expected_type(
        self, method_symbol, signature, node, context: CodeGenContext
    ) -> str | None:
        """从方法符号的 TypeInfo 中获取索引参数的期望 C++ 类型"""
        if method_symbol and method_symbol.type_info and method_symbol.type_info.args:
            from mcpy.type_system import get_cpp_type

            # __setitem__ 的参数：[self, index, value]
            # 索引参数是第二个（index=1）
            if len(method_symbol.type_info.args) >= 2:
                index_param_type_info = method_symbol.type_info.args[1]
                try:
                    cpp_type = get_cpp_type(index_param_type_info, node)
                    return cpp_type
                except:
                    pass

        return None

    def _apply_index_type_conversion(
        self,
        value_code: str,
        value_cpp_type: str | None,
        target_cpp_type: str,
        context: CodeGenContext,
    ) -> str:
        """应用索引类型转换"""
        from mcpy.codegen.utils.type_conversion import apply_variant_conversion

        result = apply_variant_conversion(value_code, value_cpp_type, target_cpp_type)
        if result != value_code:
            context.require_include("mcpy/builtins.h")
        return result

    def _try_get_subscript_reference(
        self, node: IRSubscript, obj_code: str, index_code: str, context: CodeGenContext
    ) -> str | None:
        """尝试使用类型符号的 __getitem__ 方法生成引用代码

        通过符号体系查找 __getitem__ 方法，支持 builtin 类型、用户自定义类和 stub
        用于赋值语句的左值，需要返回可以被赋值的引用。

        Args:
            node: 下标访问节点
            obj_code: 对象表达式代码
            index_code: 索引表达式代码
            context: 代码生成上下文

        Returns:
            str | None: 生成的引用代码，如果无法使用配置则返回 None
        """
        # 从推断类型获取 TypeInfo
        type_info = node.value.get_extension_param("inferred_type")
        if not type_info:
            return None

        # 获取索引的类型信息用于方法重载匹配
        index_type = node.slice.get_extension_param("inferred_type")
        args_types = [index_type] if index_type else []

        # 查找 __getitem__ 方法符号
        # 使用 IRNode.lookup_symbol（内部已经处理内置类型和用户自定义类）
        method_symbol = None
        if context.current_node:
            method_symbol = context.current_node.lookup_symbol(
                "__getitem__",
                owner_type=type_info,
                func_args=args_types,
            )

        if not method_symbol:
            return None

        # 获取匹配的签名
        matching_signature = method_symbol.find_matching_signature(
            [type_info] + args_types
        )
        if not matching_signature:
            # 如果没有找到匹配的签名，使用第一个签名
            if method_symbol.signatures:
                matching_signature = method_symbol.signatures[0]
            else:
                return None

        # 获取模板
        template = matching_signature.emit_template
        if not template:
            return None

        # 添加必要的包含文件
        includes = getattr(matching_signature, "includes", [])
        for include in includes:
            context.require_include(include)

        code = replace_template_params(
            template, matching_signature, [obj_code, index_code]
        )

        return code

    def _generate_target_code(self, target: str) -> str:
        """生成目标代码，处理属性赋值的特殊情况

        Args:
            target: 目标字符串，如 "x", "self.x", "obj.attr"

        Returns:
            str: 生成的目标代码
        """
        # 处理 self.x -> this->x
        if target.startswith("self."):
            attr_name = target[5:]  # 去掉 "self." 前缀
            return f"this->{attr_name}"

        # 其他情况直接返回
        return target

    def _try_aug_assign_overload(
        self,
        node: IRAugAssign,
        target_code: str,
        value_code: str,
        context: CodeGenContext,
    ) -> str | None:
        """尝试使用操作符重载处理增强赋值

        对于有 __ior__, __iadd__ 等方法的类型，使用重载方法

        Args:
            node: 增强赋值节点
            target_code: 目标代码
            value_code: 值代码
            context: 代码生成上下文

        Returns:
            str | None: 生成的代码，如果不需要重载则返回 None
        """
        # 操作符到增强赋值方法的映射
        op_to_iop_method = {
            "+": "__iadd__",
            "-": "__isub__",
            "*": "__imul__",
            "/": "__itruediv__",
            "//": "__ifloordiv__",
            "%": "__imod__",
            "**": "__ipow__",
            "|": "__ior__",
            "&": "__iand__",
            "^": "__ixor__",
            "<<": "__ilshift__",
            ">>": "__irshift__",
        }

        iop_method = op_to_iop_method.get(node.op)
        if not iop_method:
            return None

        # 尝试从目标变量查找类型信息
        # IRAugAssign.target 是字符串，需要通过符号表查找
        if not context.current_node:
            return None

        # 先尝试从 IR 节点的扩展参数获取类型信息（类型推断阶段设置的）
        target_type_info = node.get_extension_param("target_type")

        # 如果没有，通过父作用域查找符号
        if not target_type_info:
            # context.current_node 可能是 augassign 节点本身，需要通过父作用域查找
            parent_scope = context.current_node.get_parent_scope()
            if parent_scope:
                target_symbol = parent_scope.lookup_symbol(node.target)
                if target_symbol and hasattr(target_symbol, "type_info"):
                    target_type_info = target_symbol.type_info

            if not target_type_info:
                # 最后尝试从当前节点查找
                target_symbol = context.current_node.lookup_symbol(node.target)
                if target_symbol and hasattr(target_symbol, "type_info"):
                    target_type_info = target_symbol.type_info

        if not target_type_info:
            return None

        # 获取值的类型信息
        value_type_info = node.value.get_extension_param("inferred_type")
        # args_types 不包含 self（只有方法参数）
        args_types = [value_type_info] if value_type_info else []
        # 完整的 args_types 包含 self（用于签名匹配）
        full_args_types = [target_type_info] + args_types

        # 查找方法符号
        # 使用 IRNode.lookup_symbol（内部已经处理内置类型和用户自定义类）
        method_symbol = None
        if context.current_node:
            method_symbol = context.current_node.lookup_symbol(
                iop_method,
                owner_type=target_type_info,
                func_args=args_types,
            )

        if not method_symbol:
            return None

        # 查找匹配的签名（需要包含 self）
        matching_signature = method_symbol.find_matching_signature(full_args_types)
        if not matching_signature:
            # 如果没有找到匹配的签名，使用第一个签名
            if method_symbol.signatures:
                matching_signature = method_symbol.signatures[0]
            else:
                return None

        # 获取模板
        template = matching_signature.emit_template
        if not template:
            return None

        # 替换模板中的占位符
        # 使用签名中的实际参数名进行替换
        from ...template_system import replace_template_params

        code = replace_template_params(
            template, matching_signature, [target_code, value_code]
        )

        # 添加必要的包含文件
        includes = getattr(matching_signature, "includes", [])
        for include in includes:
            context.require_include(include)

        # 增强赋值需要生成完整的语句
        return f"{code};"

    def _get_default_value_for_type(
        self,
        cpp_type: Optional[str],
        target_expr: IRNode,
    ) -> Optional[str]:
        """获取类型的默认值

        Args:
            cpp_type: C++ 类型字符串
            annotation: 类型注解字符串
            target_expr: 目标表达式
            context: 代码生成上下文

        Returns:
            默认值字符串，如果无法确定则返回 None
        """
        symbol = target_expr.get_symbol(create_if_not_exists=False)
        if symbol and symbol.type_config:
            default_value = symbol.type_config.get("default_value")
            if default_value:
                return str(default_value)

        return f"{cpp_type}{{}}"

    def _apply_type_conversion(
        self,
        value_code: str,
        value_node: IRNode,
        target_cpp_type: Optional[str],
        context: CodeGenContext,
    ) -> str:
        """应用类型转换（variant到强类型）

        使用 mcpy 提供的辅助函数（cast.h）进行类型转换。

        Args:
            value_code: 值表达式的生成代码
            value_node: 值表达式的IR节点
            target_cpp_type: 目标变量的C++类型
            context: 代码生成上下文

        Returns:
            str: 转换后的代码（如果需要转换）或原始代码
        """
        from mcpy.codegen.utils.type_conversion import (
            apply_variant_conversion,
            apply_container_conversion,
        )

        if not target_cpp_type:
            return value_code

        # 获取值表达式的类型
        value_cpp_type = context.get_cpp_type(value_node)

        # 优先尝试容器转换（list[any] -> list[int]）
        converted_code = apply_container_conversion(
            value_code, value_cpp_type, target_cpp_type
        )
        if converted_code != value_code:
            context.require_include("mcpy/builtins.h")
            return converted_code

        # 尝试 variant 到强类型的转换
        result = apply_variant_conversion(value_code, value_cpp_type, target_cpp_type)
        if result != value_code:
            context.require_include("mcpy/builtins.h")
        return result

    def get_priority(self) -> int:
        """获取发射器优先级"""
        return 10  # 非常高的优先级，确保赋值和 global 语句被正确处理
